﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.ServiceModel;
using System.Text;
using MobileSales.Server.Database;
using MobileSales.Common.Logger;

namespace MobileSales.Server.Services
{
    public class TaskService : ServiceBase, ITaskService
    {
        #region Schedule management

        #region GetScheduleList
        public IEnumerable<Model.Tasks.Schedule> GetScheduleList(int employeeId)
        {
            this.ValidateToken();
            bool employeeExist = entities.Employees.Count(x => x.EmployeeId.Equals(employeeId)) == 1;
            if (!employeeExist)
                return null;

            IEnumerable<Schedule> dbSchedules = entities.Schedules.Where(x => x.EmployeeId.Equals(employeeId));
            if (dbSchedules != null)
            {
                List<Model.Tasks.Schedule> result = new List<Model.Tasks.Schedule>();
                foreach (var dbSchedule in dbSchedules)
                {
                    Model.Tasks.Schedule schedule = new Model.Tasks.Schedule();
                    this.FillSchedule(dbSchedule, ref schedule, false);
                    result.Add(schedule);
                }
                return result;
            }
            else
                CLogger.LogDebug("Schedule list not found");
            return null;
        } 
        #endregion

        #region GetSchedule
        public Model.Tasks.Schedule GetSchedule(int scheduleId)
        {
            this.ValidateToken();
            Schedule dbSchedule = entities.Schedules.Where(x => x.ScheduleId.Equals(scheduleId)).FirstOrDefault();
            if (dbSchedule != null)
            {
                Model.Tasks.Schedule schedule = new Model.Tasks.Schedule();
                this.FillSchedule(dbSchedule, ref schedule);
                return schedule;
            }
            else
                CLogger.LogDebug("Schedule not found");
            return null;
        }
        #endregion

        #region GetScheduleByDate
        public Model.Tasks.Schedule GetScheduleByDate(int employeeId, DateTime date)
        {
            this.ValidateToken();
            DateTime dateFrom = new DateTime(date.Year, date.Month, date.Day);
            DateTime dateTo = dateFrom + new TimeSpan(23, 59, 59);

            Schedule dbSchedule = entities.Schedules.Where(x => x.EmployeeId.Equals(employeeId)
                                                           && x.StartTime >= dateFrom && x.StartTime <= dateTo)
                                                    .FirstOrDefault();
            if (dbSchedule != null)
            {
                Model.Tasks.Schedule schedule = new Model.Tasks.Schedule();
                this.FillSchedule(dbSchedule, ref schedule);
                return schedule;
            }
            else
                CLogger.LogDebug("Schedule not found");
            return null;
        }
        #endregion

        #region FillSchedule
        private void FillSchedule(Schedule sourceSchedule, ref Model.Tasks.Schedule destSchedule, bool withTasks = true)
        {
            destSchedule.CreationDate = sourceSchedule.CreationDate;
            destSchedule.EmployeeId = sourceSchedule.EmployeeId;
            destSchedule.EndPositionLatitude = sourceSchedule.EndPosLat;
            destSchedule.EndPositionLongitude = sourceSchedule.EndPostLon;
            destSchedule.EndTime = sourceSchedule.EndTime;
            destSchedule.Id = sourceSchedule.ScheduleId;
            destSchedule.ModificationDate = sourceSchedule.ModificationDate;
            destSchedule.RealEndTime = sourceSchedule.RealEndTime;
            destSchedule.RealStartTime = sourceSchedule.RealStartTime;
            destSchedule.StartPositionLatitude = sourceSchedule.StartPosLat;
            destSchedule.StartPositionLongitude = sourceSchedule.StartPosLon;
            destSchedule.StartTime = sourceSchedule.StartTime;
            if (withTasks)
                destSchedule.Tasks = this.GetTaskList(sourceSchedule.ScheduleId);
        }
        #endregion

        #region StoreSchedule
        public void StoreSchedule(Model.Tasks.Schedule schedule)
        {
            this.ValidateToken();
            DateTime now = DateTime.Now;
            Schedule dbSchedule = null;
            if (schedule.Id != 0)
            {
                dbSchedule = entities.Schedules.Where(x => x.ScheduleId.Equals(schedule.Id)).FirstOrDefault();
                if (dbSchedule == null)
                {
                    this.Raise("Schedule not found");
                }
            }
            else
            {
                dbSchedule = new Schedule();
                dbSchedule.CreationDate = now;
            }
            dbSchedule.ModificationDate = now;
            dbSchedule.StartTime = schedule.StartTime;
            dbSchedule.EndTime = schedule.EndTime;
            dbSchedule.EmployeeId = schedule.EmployeeId;
            dbSchedule.EndPosLat = schedule.EndPositionLatitude;
            dbSchedule.EndPostLon = schedule.EndPositionLongitude;
            dbSchedule.StartPosLat = schedule.StartPositionLatitude;
            dbSchedule.StartPosLon = schedule.StartPositionLongitude;
            dbSchedule.RealEndTime = schedule.RealEndTime;
            dbSchedule.RealStartTime = schedule.RealStartTime;
            if (schedule.Id == 0)
            {
                entities.Schedules.AddObject(dbSchedule);
            }
            entities.SaveChanges();
            this.Notify(dbSchedule.EmployeeId, Util.ServiceType.TaskService, "GetSchedule", dbSchedule.ScheduleId);
        }
        #endregion

        #region DeleteSchedule
        public void DeleteSchedule(int scheduleId)
        {
            this.ValidateToken();
            Schedule dbSchedule = entities.Schedules.Where(x => x.ScheduleId.Equals(scheduleId)).FirstOrDefault();
            int employeeId = dbSchedule.EmployeeId;
            if (dbSchedule != null)
            {
                entities.Schedules.DeleteObject(dbSchedule);
                entities.SaveChanges();
                this.Notify(employeeId, Util.ServiceType.TaskService, "DeleteSchedule", scheduleId);
            }
            else
                this.Raise("Schedule not found");
        }
        #endregion

        #region StartSchedule
        public void StartSchedule(int scheduleId, double? latitude, double? longitude)
        {
            Schedule dbSchedule = entities.Schedules.Where(x => x.ScheduleId.Equals(scheduleId)).FirstOrDefault();
            if (dbSchedule != null)
            {
                this.ValidateTokenFor(dbSchedule.EmployeeId);
                dbSchedule.RealStartTime = DateTime.Now;
                dbSchedule.StartPosLat = latitude;
                dbSchedule.StartPosLon = longitude;
                entities.SaveChanges();
            }
            else
                this.Raise("Schedule not found");
        }
        #endregion

        #region EndSchedule
        public void EndSchedule(int scheduleId, double? latitude, double? longitude)
        {
            Schedule dbSchedule = entities.Schedules.Where(x => x.ScheduleId.Equals(scheduleId)).FirstOrDefault();
            if (dbSchedule != null)
            {
                this.ValidateTokenFor(dbSchedule.EmployeeId);
                dbSchedule.RealEndTime = DateTime.Now;
                dbSchedule.EndPosLat = latitude;
                dbSchedule.EndPostLon = longitude;
                entities.SaveChanges();
            }
            else
                this.Raise("Schedule not found");
        }
        #endregion

        #endregion

        #region Task management

        #region GetTask
        public Model.Tasks.Task GetTask(int taskId)
        {
            this.ValidateToken();
            Task dbTask = entities.Tasks.Where(x => x.TaskId.Equals(taskId)).FirstOrDefault();
            if (dbTask != null)
            {
                if (dbTask.Schedule == null)
                {
                    CLogger.LogDebug("Task not found");
                    return null;
                }

                Model.Tasks.Task task = new Model.Tasks.Task();
                this.FillTask(dbTask, ref task);
                return task;
            }
            else
                CLogger.LogDebug("Task not found");
            return null;
        }
        #endregion

        #region GetCyclicTask
        public Model.Tasks.CyclicTask GetCyclicTask(int taskId)
        {
            this.ValidateToken();
            Task dbTask = entities.Tasks.Where(x => x.TaskId.Equals(taskId)).FirstOrDefault();
            if (dbTask != null)
            {
                if (dbTask.Schedule != null)
                {
                    CLogger.LogDebug("Task not found");
                    return null;
                }

                EmployeeHasCyclicTask dbCyclicTask = dbTask.EmployeeHasCyclicTasks.FirstOrDefault();
                if (dbCyclicTask != null)
                {
                    Model.Tasks.Task task = new Model.Tasks.CyclicTask();
                    this.FillTask(dbTask, ref task);

                    ((Model.Tasks.CyclicTask)task).TaskInterval = dbCyclicTask.TaskInterval;
                    ((Model.Tasks.CyclicTask)task).EmployeeId = dbCyclicTask.EmployeeId;

                    return task as Model.Tasks.CyclicTask;
                }
            }
            CLogger.LogDebug("Task not found");
            return null;
        }
        #endregion

        #region GetTaskList
        public IEnumerable<Model.Tasks.Task> GetTaskList(int scheduleId)
        {
            this.ValidateToken();
            IEnumerable<Task> dbTasks = entities.Tasks.Where(x => x.ScheduleId.HasValue && x.ScheduleId.Value.Equals(scheduleId));
            if (dbTasks != null)
            {
                IList<Model.Tasks.Task> list = new List<Model.Tasks.Task>();
                foreach (var dbTask in dbTasks)
                {
                    Model.Tasks.Task task = new Model.Tasks.Task();
                    this.FillTask(dbTask, ref task);
                    list.Add(task);
                }
                return list;
            }
            else
                CLogger.LogDebug("Could not get task list");
            return null;
        }
        #endregion

        #region GetCyclicTaskList
        public IEnumerable<Model.Tasks.CyclicTask> GetCyclicTaskList(int employeeId)
        {
            this.ValidateToken();
            bool employeeExist = entities.Employees.Count(x => x.EmployeeId.Equals(employeeId)) == 1;
            if (!employeeExist)
                return null;

            IEnumerable<EmployeeHasCyclicTask> dbTasks = entities.EmployeeHasCyclicTasks.Where(x => x.EmployeeId.Equals(employeeId));
            if (dbTasks != null)
            {
                IList<Model.Tasks.CyclicTask> list = new List<Model.Tasks.CyclicTask>();
                foreach (var dbTask in dbTasks)
                {
                    Model.Tasks.Task task = new Model.Tasks.CyclicTask();
                    this.FillTask(dbTask.Task, ref task);
                    ((Model.Tasks.CyclicTask)task).TaskInterval = dbTask.TaskInterval;
                    ((Model.Tasks.CyclicTask)task).EmployeeId = dbTask.EmployeeId;
                    list.Add(task as Model.Tasks.CyclicTask);
                }
                return list;
            }
            else
                CLogger.LogDebug("Could not get task list");
            return null;
        }
        #endregion

        #region FillTask
        private void FillTask(Task sourceTask, ref Model.Tasks.Task destTask)
        {
            destTask.ClientId = sourceTask.ClientId;
            destTask.CreationDate = sourceTask.CreationDate;
            destTask.StartTime = sourceTask.StartTime;
            destTask.EndTime = sourceTask.EndTime;
            destTask.StartPositionLatitude = sourceTask.StartPosLat;
            destTask.StartPositionLongitude = sourceTask.StartPosLon;
            destTask.EndPositionLatitude = sourceTask.EndPosLat;
            destTask.EndPositionLongitude = sourceTask.EndPosLon;
            destTask.Id = sourceTask.TaskId;
            destTask.CreatorId = sourceTask.CreatorId;
            destTask.Info = sourceTask.Info;
            destTask.ModificationDate = sourceTask.ModificationDate;
            destTask.TaskStatus = this.GetTaskStatus(sourceTask.TaskStatusId);
            destTask.TaskType = this.GetTaskType(sourceTask.TaskTypeId);
            destTask.RealEndTime = sourceTask.RealEndTime;
            destTask.RealStartTime = sourceTask.RealStartTime;
            destTask.ScheduleId = sourceTask.ScheduleId;
            destTask.Priority = sourceTask.Priority;
        }

        private void FillTaskReverse(Model.Tasks.Task sourceTask, ref Task destTask)
        {
            destTask.ClientId = sourceTask.ClientId;
            destTask.StartTime = sourceTask.StartTime;
            destTask.EndTime = sourceTask.EndTime;
            destTask.StartPosLat = sourceTask.StartPositionLatitude;
            destTask.StartPosLon = sourceTask.StartPositionLongitude;
            destTask.EndPosLat = sourceTask.EndPositionLatitude;
            destTask.EndPosLon = sourceTask.EndPositionLongitude;
            destTask.TaskId = sourceTask.Id;
            destTask.Info = sourceTask.Info;
            destTask.TaskStatusId = sourceTask.TaskStatus.Id;
            destTask.TaskTypeId = sourceTask.TaskType.Id;
            destTask.RealEndTime = sourceTask.RealEndTime;
            destTask.RealStartTime = sourceTask.RealStartTime;
            destTask.ScheduleId = sourceTask.ScheduleId;
            destTask.Priority = sourceTask.Priority;
        }
        #endregion

        #region StoreTask
        public void StoreTask(Model.Tasks.Task task, int employeeId)
        {
            this.ValidateToken();

            if (task.EndTime <= task.StartTime)
                this.Raise("Task end time must be after start time");
            if (task.EndTime.Year != task.StartTime.Year ||
                task.EndTime.Month != task.StartTime.Month ||
                task.EndTime.Day != task.StartTime.Day)
            {
                this.Raise("Task start and end time must be in the same day");
            }

            #region Checking task schedule
            Schedule dbSchedule = null;
            if (task.ScheduleId.HasValue)
            {
                dbSchedule = entities.Schedules.Where(x => x.ScheduleId.Equals(task.ScheduleId.Value)).FirstOrDefault();
            }

            // if not search schedule for particular day
            if (dbSchedule == null)
            {
                dbSchedule = entities.Schedules.Where(x => x.EmployeeId.Equals(employeeId)
                                                               && x.StartTime.Year.Equals(task.StartTime.Year)
                                                               && x.StartTime.Month.Equals(task.StartTime.Month)
                                                               && x.StartTime.Day.Equals(task.StartTime.Day)).FirstOrDefault();


                // if found check task collisions
                if (dbSchedule != null)
                {
                    bool collide = entities.Tasks.Where(x => x.TaskId != task.Id).Count(x => x.ScheduleId.HasValue && x.ScheduleId.Value.Equals(dbSchedule.ScheduleId)
                                                 && x.StartTime < task.EndTime
                                                 && x.EndTime > task.StartTime) != 0;
                    if (collide)
                        this.Raise("Task collide with the schedule");
                }
                // if not found create new schedule for particular day
                else
                {
                    dbSchedule = new Schedule()
                    {
                        CreationDate = DateTime.Now,
                        StartTime = task.StartTime,
                        EndTime = task.EndTime,
                        EmployeeId = employeeId,
                        ModificationDate = DateTime.Now,
                    };
                    entities.Schedules.AddObject(dbSchedule);
                }
            }

            entities.SaveChanges();
            #endregion

            Task dbTask = null;
            if (task.Id != 0)
            {
                dbTask = entities.Tasks.Where(x => x.TaskId.Equals(task.Id)).FirstOrDefault();
                if (dbTask == null)
                {
                    this.Raise("Task not found");
                }
            }
            else
            {
                dbTask = new Task();
            }
            this.FillTaskReverse(task, ref dbTask);
            DateTime now = DateTime.Now;
            dbTask.ModificationDate = now;
            dbTask.Schedule = dbSchedule;
            if (task.Id == 0)
            {
                int creatorId = this.GetEmployeeIdFromToken();
                dbTask.CreatorId = creatorId;
                dbTask.CreationDate = now;
                entities.Tasks.AddObject(dbTask);
            }
            entities.SaveChanges();
            DateTime newStartTime = dbSchedule.Tasks.Min(x => x.StartTime);
            DateTime newEndTime = dbSchedule.Tasks.Max(x => x.EndTime);
            dbSchedule.StartTime = newStartTime;
            dbSchedule.EndTime = newEndTime;
            entities.SaveChanges();
            this.Notify(dbSchedule.EmployeeId, Util.ServiceType.TaskService, "GetSchedule", dbSchedule.ScheduleId);
        }
        #endregion

        #region StoreCyclicTask
        public void StoreCyclicTask(Model.Tasks.CyclicTask task)
        {
            this.ValidateToken();

            if (task.EndTime <= task.StartTime)
                this.Raise("Task end time must be after start time");
            if (task.EndTime.Year != task.StartTime.Year ||
                task.EndTime.Month != task.StartTime.Month ||
                task.EndTime.Day != task.StartTime.Day)
            {
                this.Raise("Task start and end time must be in the same day");
            }

            Task dbTask = null;
            if (task.Id != 0)
            {
                dbTask = entities.Tasks.Where(x => x.TaskId.Equals(task.Id)).FirstOrDefault();
                if (dbTask == null)
                {
                    this.Raise("Cyclic task not found");
                }
            }
            else
            {
                dbTask = new Task();
            }
            this.FillTaskReverse(task, ref dbTask);
            DateTime now = DateTime.Now;
            
            dbTask.ModificationDate = now;
            if (task.Id == 0)
            {
                int creatorId = this.GetEmployeeIdFromToken();
                dbTask.CreatorId = creatorId;
                dbTask.CreationDate = now;
                entities.Tasks.AddObject(dbTask);
            }
            entities.SaveChanges();

            EmployeeHasCyclicTask dbEmployeeCyclicTask = null;
            if (task.Id != 0)
            {
                dbEmployeeCyclicTask = entities.EmployeeHasCyclicTasks.Where(x => x.TaskId.Equals(task.Id)).FirstOrDefault();
                if (dbEmployeeCyclicTask == null)
                {
                    this.Raise("Cyclic Task not found");
                }
            }
            else
            {
                dbEmployeeCyclicTask = new EmployeeHasCyclicTask();
            }
            dbEmployeeCyclicTask.TaskId = dbTask.TaskId;
            dbEmployeeCyclicTask.EmployeeId = task.EmployeeId;
            dbEmployeeCyclicTask.TaskInterval = task.TaskInterval;

            if (task.Id == 0)
            {
                entities.EmployeeHasCyclicTasks.AddObject(dbEmployeeCyclicTask);
            }
            entities.SaveChanges();
            this.Notify(dbEmployeeCyclicTask.EmployeeId, Util.ServiceType.TaskService, "GetCyclicTask", dbTask.TaskId);
        }
        #endregion

        #region DeleteTask
        public void DeleteTask(int taskId)
        {
            this.ValidateToken();
            Task dbTask = entities.Tasks.Where(x => x.TaskId.Equals(taskId)).FirstOrDefault();
            if (dbTask != null)
            {
                List<int> employeeIds = new List<int>();
                if (dbTask.ScheduleId.HasValue)
                    employeeIds.Add( dbTask.Schedule.EmployeeId);
                else
                    employeeIds.AddRange( dbTask.EmployeeHasCyclicTasks.Select(x => x.EmployeeId));

                int? dbScheduleId = dbTask.ScheduleId;

                entities.Tasks.DeleteObject(dbTask);
                entities.SaveChanges();

                if (dbScheduleId.HasValue)
                {
                    Schedule dbSchedule = entities.Schedules.Where(x => x.ScheduleId.Equals(dbScheduleId.Value)).FirstOrDefault();
                    if (dbSchedule != null)
                    {
                        if (dbSchedule.Tasks.Count == 0)
                        {
                            DeleteSchedule(dbSchedule.ScheduleId);
                        }
                        else
                        {
                            DateTime newStartTime = dbSchedule.Tasks.Min(x => x.StartTime);
                            DateTime newEndTime = dbSchedule.Tasks.Max(x => x.EndTime);
                            dbSchedule.StartTime = newStartTime;
                            dbSchedule.EndTime = newEndTime;
                            entities.SaveChanges();

                        }
                    }
                }
                foreach (var id in employeeIds)
                    this.Notify(id, Util.ServiceType.TaskService, "DeleteTask", taskId);
            }
            else
                this.Raise("Task not found");
        }
        #endregion

        #region UpdateTaskStatus
        public void UpdateTaskStatus(int taskId, int taskStatusId)
        {
            this.ValidateToken();
            Task dbTask = entities.Tasks.Where(x => x.TaskId.Equals(taskId)).FirstOrDefault();
            if (dbTask != null)
            {
                dbTask.TaskStatusId = taskStatusId;
                entities.SaveChanges();
            }
            else
                this.Raise("Task not found");
        }
        #endregion

        #region StartTask

        public void StartTask(int taskId, int statusId, double? latitude, double? longitude)
        {
            this.ValidateToken();
            int employeeId = this.GetEmployeeIdFromToken();

            Task dbTask = entities.Tasks.Where(x => x.TaskId.Equals(taskId)).FirstOrDefault();
            if (dbTask != null)
            {
                dbTask.RealStartTime = DateTime.Now;
                dbTask.StartPosLat = latitude;
                dbTask.StartPosLon = longitude;
                dbTask.TaskStatusId = statusId;
                dbTask.ModificationDate = DateTime.Now;
                entities.SaveChanges();
                this.Notify(employeeId, Util.ServiceType.TaskService, (dbTask.ScheduleId.HasValue) ? "GetTask" : "GetCyclicTask", dbTask.TaskId);
            }
            else
                this.Raise("Task not found");
        }

        #endregion

        #region EndTask
        public void EndTask(int taskId, int statusId, double? latitude, double? longitude)
        {
            this.ValidateToken();
            int employeeId = this.GetEmployeeIdFromToken();

            Task dbTask = entities.Tasks.Where(x => x.TaskId.Equals(taskId)).FirstOrDefault();
            if (dbTask != null)
            {
                dbTask.RealEndTime = DateTime.Now;
                dbTask.EndPosLat = latitude;
                dbTask.EndPosLon = longitude;
                dbTask.TaskStatusId = statusId;
                dbTask.ModificationDate = DateTime.Now;
                entities.SaveChanges();

                this.Notify(employeeId, Util.ServiceType.TaskService, (dbTask.ScheduleId.HasValue) ? "GetTask" : "GetCyclicTask", dbTask.TaskId);
            }
            else
                this.Raise("Task not found");
        }
        #endregion

        #endregion

        #region Task status management

        #region GetTaskStatusList
        public IEnumerable<Model.Tasks.TaskStatus> GetTaskStatusList()
        {
            this.ValidateToken();
            IEnumerable<TaskStatus> dbTaskStatuses = entities.TaskStatuses;
            if (dbTaskStatuses != null)
            {
                IList<Model.Tasks.TaskStatus> list = new List<Model.Tasks.TaskStatus>();
                foreach (var dbTaskStatus in dbTaskStatuses)
                {
                    Model.Tasks.TaskStatus taskStatus = new Model.Tasks.TaskStatus
                    {
                        Id = dbTaskStatus.TaskStatusId,
                        Description = dbTaskStatus.Description,
                        Name = dbTaskStatus.Name
                    };
                    list.Add(taskStatus);
                }
                return list;
            }
            else
            {
                CLogger.LogDebug("Could not get task status list");
            }
            return null;
        }
        #endregion

        #region GetTaskStatus
        public Model.Tasks.TaskStatus GetTaskStatus(int taskStatusId)
        {
            this.ValidateToken();
            TaskStatus dbTaskStatus = entities.TaskStatuses.Where(x => x.TaskStatusId.Equals(taskStatusId)).FirstOrDefault();
            if (dbTaskStatus != null)
            {
                Model.Tasks.TaskStatus taskStatus = new Model.Tasks.TaskStatus
                {
                    Id = dbTaskStatus.TaskStatusId,
                    Description = dbTaskStatus.Description,
                    Name = dbTaskStatus.Name
                };
                return taskStatus;
            }
            else
            {
                CLogger.LogDebug("Task status not found");
            }
            return null;
        }
        #endregion

        #region StoreTaskStatus
        public void StoreTaskStatus(Model.Tasks.TaskStatus status)
        {
            this.ValidateToken();
            TaskStatus dbTaskStatus = null;
            if (status.Id != 0)
            {
                dbTaskStatus = entities.TaskStatuses.Where(x => x.TaskStatusId.Equals(status.Id)).FirstOrDefault();
                if (dbTaskStatus == null)
                    this.Raise("Task status not found");
            }
            else
            {
                dbTaskStatus = new TaskStatus();
            }
            dbTaskStatus.Name = status.Name;
            dbTaskStatus.Description = status.Description;
            if (status.Id == 0)
                entities.TaskStatuses.AddObject(dbTaskStatus);
            entities.SaveChanges();
            this.NotifyAll(Util.ServiceType.TaskService, "GetTaskStatus", dbTaskStatus.TaskStatusId);
        }
        #endregion

        #region DeleteTaskStatus
        public void DeleteTaskStatus(int taskStatusId)
        {
            this.ValidateToken();
            TaskStatus dbTaskStatus = entities.TaskStatuses.Where(x => x.TaskStatusId.Equals(taskStatusId)).FirstOrDefault();
            if (dbTaskStatus != null)
            {
                entities.TaskStatuses.DeleteObject(dbTaskStatus);
                entities.SaveChanges();
                this.NotifyAll(Util.ServiceType.TaskService, "DeleteTaskStatus", taskStatusId);
            }
            else
            {
                this.Raise("Task status not found");
            }
        }
        #endregion

        #endregion

        #region Task type management

        #region GetTaskTypeList
        public IEnumerable<Model.Tasks.TaskType> GetTaskTypeList()
        {
            this.ValidateToken();
            IEnumerable<TaskType> dbTaskTypes = entities.TaskTypes;
            if (dbTaskTypes != null)
            {
                IList<Model.Tasks.TaskType> list = new List<Model.Tasks.TaskType>();
                foreach (var dbTaskType in dbTaskTypes)
                {
                    Model.Tasks.TaskType taskType = new Model.Tasks.TaskType
                    {
                        Id = dbTaskType.TaskTypeId,
                        Description = dbTaskType.Description,
                        Name = dbTaskType.Name
                    };
                    list.Add(taskType);
                }
                return list;
            }
            else
            {
                CLogger.LogDebug("Could not get task type list");
            }
            return null;
        }
        #endregion

        #region GetTaskType
        public Model.Tasks.TaskType GetTaskType(int taskTypeId)
        {
            this.ValidateToken();
            TaskType dbTaskType = entities.TaskTypes.Where(x => x.TaskTypeId.Equals(taskTypeId)).FirstOrDefault();
            if (dbTaskType != null)
            {
                Model.Tasks.TaskType taskType = new Model.Tasks.TaskType
                {
                    Id = dbTaskType.TaskTypeId,
                    Description = dbTaskType.Description,
                    Name = dbTaskType.Name
                };
                return taskType;
            }
            else
            {
                CLogger.LogDebug("Task type not found");
            }
            return null;
        }
        #endregion

        #region StoreTaskType
        public void StoreTaskType(Model.Tasks.TaskType type)
        {
            this.ValidateToken();
            TaskType dbTaskType = null;
            if (type.Id != 0)
            {
                dbTaskType = entities.TaskTypes.Where(x => x.TaskTypeId.Equals(type.Id)).FirstOrDefault();
                if (dbTaskType == null)
                    this.Raise("Task type not found");
            }
            else
            {
                dbTaskType = new TaskType();
            }
            dbTaskType.Name = type.Name;
            dbTaskType.Description = type.Description;
            if (type.Id == 0)
                entities.TaskTypes.AddObject(dbTaskType);
            entities.SaveChanges();
            this.NotifyAll(Util.ServiceType.TaskService, "GetTaskType", dbTaskType.TaskTypeId);
        }
        #endregion

        #region DeleteTaskType
        public void DeleteTaskType(int taskTypeId)
        {
            this.ValidateToken();
            TaskType dbTaskType = entities.TaskTypes.Where(x => x.TaskTypeId.Equals(taskTypeId)).FirstOrDefault();
            if (dbTaskType != null)
            {
                entities.TaskTypes.DeleteObject(dbTaskType);
                entities.SaveChanges();
                this.NotifyAll(Util.ServiceType.TaskService, "DeleteTaskType", taskTypeId);
            }
            else
            {
                this.Raise("Task type not found");
            }
        }
        #endregion

        #endregion
    }
}
